/*
 * iap.c
 *
 *  Created on: 2025年9月1日
 *      Author: sxy
 */
#include "iap.h"
#include "usart.h"
#include "fsl_flash.h"
#include "fsl_k4_flash.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
/*  In case of the protected sectors at the end of the pFlash just select
 *	the block from the end of pFlash to be used for operations
 *	SECTOR_INDEX_FROM_END = 1 means the last sector,
 *	SECTOR_INDEX_FROM_END = 2 means (the last sector - 1) ...
 */
#ifndef SECTOR_INDEX_FROM_END
#define SECTOR_INDEX_FROM_END 1U
#endif

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void error_trap(void);
/*******************************************************************************
 * Variables
 ******************************************************************************/

/* Flash Used to record Next Jump Address */
status_t result;    /* Return code from each flash driver function */
uint32_t destAdrss; /* Address of the target location */
uint32_t pflashBlock0Base = 0;
uint32_t pflashBlock0Size = 0;
uint32_t pflashSectorSize = 0;
uint32_t pflashBlockCount = 0;
uint32_t pflashTotalSize  = 0;
/*! @brief Flash driver Structure */
static flash_config_t s_flashDriver;
/*! @brief Buffer for readback */
static uint32_t s_buffer_rbc[2];//debug使用
static uint8_t s_buffer_rbc_temp[FLASH_SECTOR_SIZE];//debug使用
static uint32_t s_buffer[1] = {0x00020000};//此工程APP的对端APP地址

/* Flash Used to write bin */
uint32_t destAdrss_App = 0; /* Address of the target location */
uint8_t NowFlash_Index = 0;
uint8_t wirte_status = 0;
/*******************************************************************************
 * Code
 ******************************************************************************/
/*
 * @brief Gets called when an error occurs.
 *
 * @details Print error message and trap forever.
 */
void error_trap(void)
{
    PRINTF("\r\n\r\n\r\n\t---- HALTED DUE TO FLASH ERROR! ----");
    while (1)
    {
    }
}


void UQ_Flash_init(void)
{
    /* Clean up Flash, Cache driver Structure*/
    memset(&s_flashDriver, 0, sizeof(flash_config_t));
    /* Setup flash driver structure for device and initialize variables. */
    result = FLASH_Init(&s_flashDriver);
    if (kStatus_FLASH_Success != result)
    {
        error_trap();
    }

    /* Get flash properties*/
    FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0BlockBaseAddr, &pflashBlock0Base);
    FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0BlockSize, &pflashBlock0Size);
    FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0SectorSize, &pflashSectorSize);
    FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0BlockCount, &pflashBlockCount);
    FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0TotalSize, &pflashTotalSize);
//    PRINTF("\r\n Program Flash block bass address:\t%d, Hex: (0x%x)", (pflashBlock0Base / 1024), pflashBlock0Base);
//    PRINTF("\r\n Program Flash block Size:\t\t%d KB, Hex: (0x%x)", (pflashBlock0Size / 1024), pflashBlock0Size);
//    PRINTF("\r\n Program Flash block Sector Size:\t%d KB, Hex: (0x%x)", (pflashSectorSize / 1024), pflashSectorSize);
//    PRINTF("\r\n Program Flash block count Size:\t%d", pflashBlockCount);
//    PRINTF("\r\n Total Program Flash Size:\t\t%d KB, Hex: (0x%x)\r\n", (pflashTotalSize / 1024), pflashTotalSize);

	destAdrss_App = s_buffer[0];

	result    = FLASH_Erase(&s_flashDriver, FLASH, destAdrss_App, 0x10000, kFLASH_ApiEraseKey);
	if (kStatus_FLASH_Success != result)
	{
		error_trap();
	}
}

void Flash_UpdateFlag(void)
{
    /* Erase a sector from destAdrss. */
     destAdrss = pflashBlock0Base;
     result    = FLASH_Erase(&s_flashDriver, FLASH, destAdrss, pflashSectorSize, kFLASH_ApiEraseKey);
     if (kStatus_FLASH_Success != result)
     {
         error_trap();
     }

     /* Program user buffer into flash */
     result = FLASH_Program(&s_flashDriver, FLASH, destAdrss, (uint8_t *)s_buffer, 4);
     if (kStatus_FLASH_Success != result)
     {
         error_trap();
     }

     s_buffer_rbc[0] = destAdrss;
     s_buffer_rbc[1] = *(volatile uint32_t *)(destAdrss);
     PRINTF("APP1_Address: %08X\r\n", s_buffer_rbc[0]);
     PRINTF("APP1_Value: %08X\r\n", s_buffer_rbc[1]);
}

void Flash_App(uint8_t *Sector_Msg)
{
	destAdrss_App = s_buffer[0] + NowFlash_Index*pflashSectorSize;

	if(NowFlash_Index%2 == 0)
	{
		PRINTF("startErase\r\n");
		result    = FLASH_Erase(&s_flashDriver, FLASH, destAdrss_App, pflashSectorSize, kFLASH_ApiEraseKey);
		if (kStatus_FLASH_Success != result)
		{
			error_trap();
			wirte_status = 1;
		}
	}

	PRINTF("startProgramAddress：%08X\r\n",destAdrss_App);

	/* Program user buffer into flash */
	result = FLASH_Program(&s_flashDriver, FLASH, destAdrss_App, Sector_Msg, pflashSectorSize);
	if (kStatus_FLASH_Success != result)
	{
		error_trap();
		wirte_status = 1;
	}

	PRINTF("startcompare\r\n");

    /* Verify programming by reading back from flash directly */
    for (uint32_t i = 0; i < pflashSectorSize; i++)
    {
    	s_buffer_rbc_temp[i] = *(volatile uint32_t *)(destAdrss_App + i);
        if (s_buffer_rbc_temp[i] != Sector_Msg[i])
        {
            error_trap();
            wirte_status = 1;
        }
    }

    PRINTF("success\r\n");
    PRINTF("4092----%08X\r\n",s_buffer_rbc_temp[4092]);
    PRINTF("4093----%08X\r\n",s_buffer_rbc_temp[4093]);
    PRINTF("4094----%08X\r\n",s_buffer_rbc_temp[4094]);
    PRINTF("4095----%08X\r\n",s_buffer_rbc_temp[4095]);

	if(wirte_status == 0)
	{
		NowFlash_Index++;
	}
	else
	{
		wirte_status = 0;
	}

}






